package org.timemachine.forward;

import java.lang.reflect.Field;
import java.util.Date;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.ejb.Schedule;
import javax.ejb.Singleton;
import javax.ejb.Startup;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TemporalType;

import org.timemachine.context.ScheduleContext;
import org.timemachine.context.TMScheduleThreadLocal;
import org.timemachine.factory.EntityChangeFactory;
import org.timemachine.factory.spi.EntityChange;
import org.timemachine.model.base.ForwardEntity;

@Singleton
@Startup
public class ForwardScheduleBean {

	@PersistenceContext
	EntityManager entityManager;

	@Schedule(hour = "*", minute = "*/30", second = "0", persistent = false)
	@PostConstruct
	public void run() throws Exception {

		List<ForwardEntity> forwardEntities = entityManager
				.createQuery(
						"select e from ForwardEntity e where e.forwardChangeInfo.processTimeStamp is null"
								+ " and  e.forwardChangeInfo.changeTimeStamp <= :currentDate ",
						ForwardEntity.class)
				.setParameter("currentDate", new Date(), TemporalType.TIMESTAMP)
				.getResultList();
		for (ForwardEntity forwardEntity : forwardEntities) {
			Object entity = entityManager
					.createQuery(
							"select e from "
									+ forwardEntity.getEntityName()
									+ " e where e.beginChangeInfo.id = :beginChangeInfoId")
					.setParameter("beginChangeInfoId",
							forwardEntity.getForwardChangeInfo().getId())
					.getSingleResult();

			EntityChange entityChange = (EntityChange) entity;
			ScheduleContext context = new ScheduleContext();
			context.setSchedule(true);
			TMScheduleThreadLocal.set(context);
			if (entityChange.getChangeType() == EntityChangeFactory.CHANGE_TYPE_INSERT) {
				Class<?> cls;
				String className = entityChange.getClass().getName();
				className = className.replace("Change", "");
				cls = Class.forName(className);
				Object objEntity = cls.newInstance();

				EntityChangeFactory.copyPropertiesEntity(objEntity,
						entityChange);

				Field objectId = cls.getDeclaredField(entityChange
						.getEntityPrimaryKeyName());
				objectId.setAccessible(true);
				Field chengeObjectId = entityChange.getClass()
						.getDeclaredField(
								entityChange.getEntityPrimaryKeyName());
				chengeObjectId.setAccessible(true);
				objectId.set(objEntity, null);

				entityManager.persist(objEntity);
				chengeObjectId.set(entityChange, objectId.get(objEntity));

				//Unit unit = new Unit();
				//EntityChangeFactory.copyPropertiesEntity(unit, entityChange);
				//unit.setId(null);
				//entityManager.persist(unit);
			}
			forwardEntity.getForwardChangeInfo()
					.setProcessTimeStamp(new Date());
			entityManager.merge(forwardEntity.getForwardChangeInfo());

		}

	}
}
